export const title = "Advanced Filtering"

# Advanced Filtering - Nested Filters

## Step 1: Create a Collection

Start by creating a collection named `dinosaurs` with a vector size of 4 and the distance metric set to `Dot`:

```json withRunButton="true"
PUT collections/dinosaurs
{
  "vectors": {
    "size": 4,
    "distance": "Dot"
  }
}
```

## Step 2: Add Vectors with Payloads

You can now add points to the collection. Each point contains an `id`,  `vector` and a `payload` with additional information such as the dinosaur species and diet preferences. For example:

```json withRunButton="true"
PUT collections/dinosaurs/points
{
  "points": [
    {
      "id": 1,
      "vector": [0.1, 0.2, 0.3, 0.4],
      "payload": {
        "dinosaur": "t-rex",
        "diet": [
          { "food": "leaves", "likes": false },
          { "food": "meat", "likes": true }
        ]
      }
    },
    {
      "id": 2,
      "vector": [0.2, 0.3, 0.4, 0.5],
      "payload": {
        "dinosaur": "diplodocus",
        "diet": [
          { "food": "leaves", "likes": true },
          { "food": "meat", "likes": false }
        ]
      }
    }
  ]
}
```


## Step 3: Index the fields before filtering

**Note:** You should always index a field before filtering. If you use filtering before you create an index, Qdrant will search through the entire dataset in an unstructured way. Your search performance will be very slow.

```json withRunButton="true"
PUT /collections/dinosaurs/index
{
    "field_name": "diet[].food",
    "field_schema": "keyword"
}
```

```json withRunButton="true"
PUT /collections/dinosaurs/index
{
    "field_name": "diet[].likes",
    "field_schema": "bool"
}
```

## Step 4: Basic Filtering with `match`

You can filter points by specific payload values. For instance, the query below matches points where:

- The `diet[].food` contains "meat".
- The `diet[].likes` is set to `true`.

Both points match these conditions, as:
- The “t-rex” eats meat and likes it.
- The “diplodocus” eats meat but doesn't like it.

```json withRunButton="true"
POST /collections/dinosaurs/points/scroll
{
  "filter": {
    "must": [
      {
        "key": "diet[].food",
        "match": {
          "value": "meat"
        }
      },
      {
        "key": "diet[].likes",
        "match": {
          "value": true
        }
      }
    ]
  }
}
```

However, if you want to retrieve only the points where both conditions are true for the same element within the array (e.g., the "t-rex" with ID 1), you'll need to use a **nested filter**.

## Step 5: Advanced Filtering with Nested Object Filters

To apply the filter at the array element level, you use the `nested` filter condition. This ensures that the `food` and `likes` values are evaluated together within each array element:

```json withRunButton="true"
POST /collections/dinosaurs/points/scroll
{
  "filter": {
    "must": [
      {
        "nested": {
          "key": "diet",
          "filter": {
            "must": [
              {
                "key": "food",
                "match": {
                  "value": "meat"
                }
              },
              {
                "key": "likes",
                "match": {
                  "value": true
                }
              }
            ]
          }
        }
      }
    ]
  }
}
```

With this filter, only the "t-rex" (ID 1) is returned, because its array element satisfies both conditions.

### Explanation

Nested filters treat each array element as a separate object, applying the filter independently to each element. The parent document (in this case, the dinosaur point) matches the filter if any one array element meets all conditions.

## Step 6: Combining `has_id` with Nested Filters

Note that `has_id` cannot be used inside a nested filter. If you need to filter by ID as well, include the `has_id` condition as a separate clause, like this:

You won't get a different answer. You can see that this filter matches the "t-rex" (ID 1) by combining the `nested` diet filter with an explicit ID match.

```json withRunButton="true"
POST /collections/dinosaurs/points/scroll
{
  "filter": {
    "must": [
      {
        "nested": {
          "key": "diet",
          "filter": {
            "must": [
              {
                "key": "food",
                "match": {
                  "value": "meat"
                }
              },
              {
                "key": "likes",
                "match": {
                  "value": true
                }
              }
            ]
          }
        }
      },
      {
        "has_id": [1]
      }
    ]
  }
}
```

